﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

using weber.Base;

namespace weber
{
	/// <summary>
	/// main form
	/// </summary>
	public partial class MainForm : Form
	{
		/// <summary>
		/// current page that is being displayed to the user. must be changed every time user changes the tab page
		/// </summary>
		BaseTabPage CurrentTabPage { get; set; }

		/// <summary>
		/// default
		/// </summary>
		public MainForm()
		{
			InitializeComponent();
		}

		/// <summary>
		/// main form load
		/// </summary>
		private void MainForm_Load(object sender, EventArgs e)
		{
			// load the first tab page
			AddTabPageToTab();

			// go home url
			CurrentTabPage.Browser.GoHome();

			// set focus
			txtUrl.Focus();
		}

		/// <summary>
		/// add a new tab page to the main tab control
		/// </summary>
		void AddTabPageToTab()
		{
			BaseTabPage page = new BaseTabPage();
			page.Browser = GetBrowser();
			MainTab.TabPages.Add(page);
			CurrentTabPage = page;
			SetTabPageTitle(page.Browser);
		}

		/// <summary>
		/// setup a basebrowser object to be used in a tab
		/// </summary>
		BaseWebBrowser GetBrowser()
		{
			BaseWebBrowser result = new BaseWebBrowser();
			result.Navigating += new WebBrowserNavigatingEventHandler(MainBrowser_Navigating);
			result.Navigated += new WebBrowserNavigatedEventHandler(MainBrowser_Navigated);
			result.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(MainBrowser_DocumentCompleted);
			result.StatusTextChanged += new EventHandler(MainBrowser_StatusTextChanged);
			result.ScriptErrorsSuppressed = true;
			return result;
		}

		/// <summary>
		/// set the status text of the browser to the status text of the main window
		/// </summary>
		void MainBrowser_StatusTextChanged(object sender, EventArgs e)
		{
			BaseWebBrowser browser = sender as BaseWebBrowser;
			if (browser == CurrentTabPage.Browser)
			{
				this.lblStatus.Text = browser.StatusText;
			}
		}

		/// <summary>
		/// raised before the browser navigates to a url
		/// </summary>
		private void MainBrowser_Navigating(object sender, System.Windows.Forms.WebBrowserNavigatingEventArgs e)
		{
			// store the url in the global store
			BaseWebBrowser browser = sender as BaseWebBrowser;
			Helper.SaveRequest(browser.BrowserId, e.Url);
			SetWaitCursor(browser);
		}

		/// <summary>
		/// raised after navigation is complete
		/// </summary>
		void MainBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
		{
			string au = e.Url.AbsoluteUri.ToLower();
			if (au.Contains("navcancl.htm"))
			{
				// yes, DocumentCompleted event will not be raised, raise it ourselves
				MainBrowser_DocumentCompleted(sender, null);
			}
		}

		/// <summary>
		/// raised after the browser completes the loading of the document
		/// </summary>
		void MainBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
		{
			DeleteRequestAfterEvents(sender as BaseWebBrowser);
		}

		/// <summary>
		/// delete the original request from global store after the events:
		/// - navigated
		/// - documentcomplete
		/// </summary>
		void DeleteRequestAfterEvents(BaseWebBrowser browser)
		{
			// delete the request from global store
			Helper.DeleteRequest(browser.BrowserId);

			// set url
			txtUrl.Text = browser.Url.AbsoluteUri;

			// set title
			SetTabPageTitle(browser);

			// reset cursor
			SetDefaultCursor(browser);

			// reset status text
			this.lblStatus.Text = string.Empty;
		}

		const int TabPageTitleLength = 25;
		/// <summary>
		/// set the title for the tab page
		/// </summary>
		void SetTabPageTitle(BaseWebBrowser browser)
		{
			BaseTabPage page = browser.Parent as BaseTabPage;
			string title = browser.DocumentTitle.Trim();

			// set the tool tip as full title
			page.ToolTipText = title;

			// set the page title
			StringBuilder sb = new StringBuilder();
			if (title.Length >= TabPageTitleLength)
			{
				sb.Append(title.Substring(0, TabPageTitleLength - 3));
				sb.Append("...");
				page.Text = sb.ToString();
			}
			else
			{
				sb.Append(title);
				sb.Append(new string(' ', TabPageTitleLength - title.Length));
				page.Text = sb.ToString();
			}
		}

		/// <summary>
		/// user clicks back button
		/// </summary>
		private void btnBack_Click(object sender, EventArgs e)
		{
			CurrentTabPage.Browser.GoBack();
		}

		/// <summary>
		/// user presses key in the url box
		/// </summary>
		private void txtUrl_KeyPress(object sender, KeyPressEventArgs e)
		{
			if (e.KeyChar == (char)13)
			{
				if (!string.IsNullOrWhiteSpace(txtUrl.Text))
				{
					// navigate if there is a non-empty url
					CurrentTabPage.Browser.Navigate(txtUrl.Text.Trim());
				}
			}
		}

		/// <summary>
		/// user clicks stop button
		/// </summary>
		private void btnStop_Click(object sender, EventArgs e)
		{
			CurrentTabPage.Browser.Stop();
		}

		/// <summary>
		/// user clicks forward button
		/// </summary>
		private void btnForward_Click(object sender, EventArgs e)
		{
			CurrentTabPage.Browser.GoForward();
		}

		/// <summary>
		/// user clicks refresh button
		/// </summary>
		private void btnRefresh_Click(object sender, EventArgs e)
		{
			CurrentTabPage.Browser.Refresh(WebBrowserRefreshOption.Completely);
		}

		/// <summary>
		/// user clicks on the url text box
		/// </summary>
		private void txtUrl_Click(object sender, EventArgs e)
		{
			ToolStripTextBox txt = sender as ToolStripTextBox;
			if (txt.SelectionLength == 0)
			{
				// if the text box doesn't have focus, select all the text in there
				txt.Select(0, txt.Text.Length);
			}
		}

		/// <summary>
		/// form is closing
		/// </summary>
		private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
		{
			// cleanup
			Helper.AppCleanup();
		}

		/// <summary>
		/// set wait cursor for this form, but set default cursor for certain elements
		/// </summary>
		void SetWaitCursor(BaseWebBrowser browser)
		{
			this.Cursor = Cursors.WaitCursor;
			this.MainTab.Cursor = Cursors.WaitCursor;
			this.CurrentTabPage.Cursor = Cursors.WaitCursor;
			MainMenu.Cursor = Cursors.Default;
			Toolbar.Cursor = Cursors.Default;
		}

		/// <summary>
		/// set the default cursor on this form
		/// </summary>
		void SetDefaultCursor(BaseWebBrowser browser)
		{
			this.Cursor = Cursors.Default;
			this.MainTab.Cursor = Cursors.Default;
			this.CurrentTabPage.Cursor = Cursors.Default;
		}
	}
}
